package com.example.recordingpen_datacollection.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.recordingpen_datacollection.Utils.AIUtil.AIChangeUtil;
import com.example.recordingpen_datacollection.Utils.AIUtil.ChatGlmDto;
import com.example.recordingpen_datacollection.Utils.AIUtil.ExecuteSSEUtil;
import com.example.recordingpen_datacollection.Utils.AIUtil.SSEListener;
import com.example.recordingpen_datacollection.Utils.SizeListUtil.LimitedSizeList;
import com.example.recordingpen_datacollection.Utils.http.BDAIokHttpUtil;
import com.example.recordingpen_datacollection.Utils.http.BDokHttpUtil;
import com.example.recordingpen_datacollection.Utils.http.Messages;
import com.example.recordingpen_datacollection.config.constant.ConstantName;
import com.example.recordingpen_datacollection.entity.Aiconsult;
import com.example.recordingpen_datacollection.entity.BaiduKey;
import com.example.recordingpen_datacollection.entity.Limituseradmin;
import com.example.recordingpen_datacollection.entity.Query.AiconsultQue;
import com.example.recordingpen_datacollection.entity.Vo.AISumUp;
import com.example.recordingpen_datacollection.entity.Vo.BDAISumUp;
import com.example.recordingpen_datacollection.mapper.AiconsultMapper;
import com.example.recordingpen_datacollection.redisService.RedisService;
import com.example.recordingpen_datacollection.result.RLIST;
import com.example.recordingpen_datacollection.result.exceptionhandler.JWException;
import com.example.recordingpen_datacollection.service.AiconsultService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.recordingpen_datacollection.service.BaiduKeyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

import static com.example.recordingpen_datacollection.Utils.http.HttpUrl.*;
import static com.example.recordingpen_datacollection.config.constant.ConstantName.*;


/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author xg
 * @since 2024-05-23
 */
@Service
public class AiconsultServiceImpl extends ServiceImpl<AiconsultMapper, Aiconsult> implements AiconsultService {
    @Autowired
    private RedisService redisService;
    @Autowired
    private BaiduKeyService baiduKeyService;
    @Transactional
    @Override
    public String BDERNIE_Speed(BDAISumUp aiSumUp, Integer loginId) {

//        if(redisService.)

        LimitedSizeList<Messages> messageslist = null;
//        redisService.delKeyData(ConstantName.DB_MESSAGES_LIST);
        if(!redisService.getKeyData(BD_MESSAGES_LIST+"-"+loginId)){
            messageslist = new LimitedSizeList<>();
            Messages messages = new Messages();
            messages.setRole("user");
            messages.setContent(aiSumUp.getContent());
            messageslist.add(messages);

        } else {
            messageslist = JSON.parseObject((String) redisService.getValue(BD_MESSAGES_LIST+"-"+loginId),LimitedSizeList.class);
            Messages messages = new Messages();
            messages.setRole("user");
            messages.setContent(aiSumUp.getContent());
            messageslist.add(messages);
        }




        String txtSumUp = "";
        String access_token = null;
//        List<BaiduKey> list = baiduKeyService.list();
        access_token = baiduKeyService.payBDtoken();
        if(access_token == null){
            throw new JWException(500,"获取key失败");
        }
//        if(!redisService.getKeyData(BD_TOKEN_CUT)){
//            redisService.setValue(BD_TOKEN_CUT, true);
//        }
//        boolean bd_token_cut = (Boolean) redisService.getValue(BD_TOKEN_CUT);
//        if(bd_token_cut){
//            boolean bd_access_token = redisService.getKeyData(BD_ACCESS_TOKEN);
//            if(!bd_access_token){
//                try {
//                    String bDtokenData = BDokHttpUtil.getBDtoken();
//                    JSONObject jsonObject = JSON.parseObject(bDtokenData);
//
//                    // 从JSONObject中提取值
//                    access_token = jsonObject.getString("access_token");
//                    int expires_in = jsonObject.getIntValue("expires_in")-(100*1000);
//                    redisService.setTokenValue2(BD_ACCESS_TOKEN,expires_in,access_token);
//                    System.out.println("重新调用token");
//                } catch (IOException e) {
//                    throw new JWException(500,"获取DB_token异常");
//                }
//            } else {
//                access_token = (String)redisService.getValue(BD_ACCESS_TOKEN);
//                System.out.println("没有调用token");
//            }
//        } else {
//            boolean bd_access_token = redisService.getKeyData(BD_ACCESS_TOKEN_V2);
//            if(!bd_access_token){
//                try {
//                    String bDtokenData = BDAIokHttpUtil.getBDtoken();
//                    JSONObject jsonObject = JSON.parseObject(bDtokenData);
//
//                    // 从JSONObject中提取值
//                    access_token = jsonObject.getString("access_token");
//                    int expires_in = jsonObject.getIntValue("expires_in")-(100*1000);
//                    redisService.setTokenValue2(BD_ACCESS_TOKEN_V2,expires_in,access_token);
//                    System.out.println("重新调用token_V2");
//                } catch (IOException e) {
//                    throw new JWException(500,"获取DB_token异常");
//                }
//            } else {
//                access_token = (String)redisService.getValue(BD_ACCESS_TOKEN_V2);
//                System.out.println("没有调用token_V2");
//            }
//        }

        /**
         * 数据记录
         */

        Aiconsult aiconsult = new Aiconsult();
        aiconsult.setLoginId(loginId);
        aiconsult.setProblem(aiSumUp.getContent());
        aiconsult.setUsageFrequency((long) aiSumUp.getContent().length());
        boolean save = this.save(aiconsult);
        if(!save){
            throw new JWException(500,"数据添加异常");
        }
        try {
            String urlData = BDurl8KData;
            if(aiSumUp.getContent().contains("+") ||
                    aiSumUp.getContent().contains("-") ||
                    aiSumUp.getContent().contains("*") ||
                    aiSumUp.getContent().contains("/") ||
                    aiSumUp.getContent().contains("加") ||
                    aiSumUp.getContent().contains("减") ||
                    aiSumUp.getContent().contains("乘") ||
                    aiSumUp.getContent().contains("除") ){
                urlData = BDAIurlData_special;

            } else if (aiSumUp.getContent().contains("天气") ||
                       aiSumUp.getContent().contains("气温") ||
                       aiSumUp.getContent().contains("星期") ||
                       aiSumUp.getContent().contains("周几") ||
                       aiSumUp.getContent().contains("日期") ||
                       aiSumUp.getContent().contains("几号") ||
                       aiSumUp.getContent().contains("时间") ||
                       aiSumUp.getContent().contains("年份")){
                urlData = BDAIurlData_special;
            }

            String messagesJson = JSON.toJSONString(messageslist);
            String  getBDData = BDokHttpUtil.getBDData(urlData,access_token, messagesJson);
            JSONObject jsonObject = JSON.parseObject(getBDData);
            String error_code = jsonObject.getString("error_code");
            if(error_code != null){

//                redisService.setValue(BD_TOKEN_CUT, (!bd_token_cut));
                throw new JWException(500,getBDData);
            }
            // 从JSONObject中提取值
            txtSumUp = jsonObject.getString("result");

        } catch (IOException e) {
            throw new JWException(500,"访问DB异常");
        }



        /**
         * 数据存储记录
         */
        Aiconsult aiconsult_finalResult = new Aiconsult();
        aiconsult_finalResult.setId(aiconsult.getId());
        aiconsult_finalResult.setFinalResult(txtSumUp);
        boolean save_Result = this.updateById(aiconsult_finalResult);
        if(!save_Result){
            throw new JWException(500,"数据添加修改");
        }




        Messages messages = new Messages();
        messages.setRole("assistant");
        messages.setContent(txtSumUp);
        messageslist.add(messages);
        redisService.setTokenValue(BD_MESSAGES_LIST+"-"+loginId,2,JSON.toJSONString(messageslist));
//        System.out.println("JSON.toJSONString(messageslist) : "+ JSON.toJSONString(messageslist));
//        System.out.println("messages.size() : "+ messageslist.size());
        //删除没必要的字符
        String replaceStr = new AIChangeUtil().replaceStr(txtSumUp);
        return replaceStr;
    }

    @Override
    public void BDERNIE_stream(BDAISumUp aiSumUp, Integer loginId, HttpServletResponse rp) {


        LimitedSizeList<Messages> messageslist = null;
        if(!redisService.getKeyData(BD_MESSAGES_LIST+"-"+loginId)){
            messageslist = new LimitedSizeList<>();
            Messages messages = new Messages();
            messages.setRole("user");
            messages.setContent(aiSumUp.getContent());
            messageslist.add(messages);

        } else {
            messageslist = JSON.parseObject((String) redisService.getValue(BD_MESSAGES_LIST+"-"+loginId),LimitedSizeList.class);
            for (Messages messages : messageslist) {
                if(messages.getContent() == null || messages.getContent().isEmpty()){
                    messageslist= new LimitedSizeList<>();
                    break;
                }
            }
            Messages messages = new Messages();
            messages.setRole("user");
            messages.setContent(aiSumUp.getContent());
            messageslist.add(messages);
        }




        String txtSumUp = "";
        String access_token = null;
        access_token = baiduKeyService.payBDtoken();
        if(access_token == null){
            throw new JWException(500,"获取key失败");
        }

        /**
         * 数据记录
         */

        Aiconsult aiconsult = new Aiconsult();
        aiconsult.setLoginId(loginId);
        aiconsult.setProblem(aiSumUp.getContent());
        aiconsult.setUsageFrequency((long) aiSumUp.getContent().length());
        boolean save = this.save(aiconsult);
        if(!save){
            throw new JWException(500,"数据添加异常");
        }
        String urlData = BDurl8KData;
        if(aiSumUp.getContent().contains("+") ||
                aiSumUp.getContent().contains("-") ||
                aiSumUp.getContent().contains("*") ||
                aiSumUp.getContent().contains("/") ||
                aiSumUp.getContent().contains("加") ||
                aiSumUp.getContent().contains("减") ||
                aiSumUp.getContent().contains("乘") ||
                aiSumUp.getContent().contains("除") ){
            urlData = BDAIurlData_special;

        } else if (aiSumUp.getContent().contains("天气") ||
                aiSumUp.getContent().contains("气温") ||
                aiSumUp.getContent().contains("星期") ||
                aiSumUp.getContent().contains("周几") ||
                aiSumUp.getContent().contains("日期") ||
                aiSumUp.getContent().contains("几号") ||
                aiSumUp.getContent().contains("时间") ||
                aiSumUp.getContent().contains("年份")){
            urlData = BDAIurlData_special;
        }

//        String messagesJson = JSON.toJSONString(messageslist);
        ChatGlmDto chatGlmDto = new ChatGlmDto();
        chatGlmDto.setMessages(messageslist);
        chatGlmDto.setMessageId(loginId+"");
        chatGlmDto.setSystem("小飞");
        try {
            String token = access_token;
            SSEListener sseListener = new SSEListener(chatGlmDto, rp);
//            System.out.println(JSON.toJSONString(chatGlmDto));
            ExecuteSSEUtil.executeSSE(urlData, token, sseListener, JSON.toJSONString(chatGlmDto));

            List<String> output = sseListener.getOutput();
            if (output == null || output.size()<=0){
                throw new JWException(500,"无数据");
            }

            for (String s : output) {
                JSONObject jsonObject =  JSONObject.parseObject(s);
                boolean resultBool = jsonObject.getBoolean("is_end");
                if(resultBool){
                    continue;
                }
                String result = jsonObject.getString("result");
                txtSumUp+=result;
                System.out.println(result);

            }
        } catch (Exception e) {
            log.error("请求SSE错误处理", e);
        }
//        toString

        /**
         * 数据存储记录
         */
        Aiconsult aiconsult_finalResult = new Aiconsult();
        aiconsult_finalResult.setId(aiconsult.getId());
        aiconsult_finalResult.setFinalResult(txtSumUp);
        boolean save_Result = this.updateById(aiconsult_finalResult);
        if(!save_Result){
            throw new JWException(500,"数据添加修改");
        }

            Messages messages = new Messages();
            messages.setRole("assistant");
            messages.setContent(txtSumUp);
            messageslist.add(messages);
            redisService.setTokenValue(BD_MESSAGES_LIST+"-"+loginId,2,JSON.toJSONString(messageslist));
            System.out.println("JSON.toJSONString(messageslist) : "+ JSON.toJSONString(messageslist) +" 332");
            System.out.println("messages.size() : "+ messageslist.size());

        //删除没必要的字符
//        String replaceStr = new AIChangeUtil().replaceStr(txtSumUp);

    }

    @Override
    public RLIST getAiconsultPage(AiconsultQue aiconsultQue, Integer value, int length) {

        QueryWrapper wrapper = new QueryWrapper();
        if(value != null && value > 0){
            wrapper.eq("login_id",value);
        }
        wrapper.orderByDesc("id");
        Page<Aiconsult> page = new Page<>(aiconsultQue.getPageNo(), aiconsultQue.getPageSize());
        this.page(page, wrapper);
        long total = page.getTotal();
        List<Aiconsult> list = page.getRecords();

        long numPage = 0;
        if(total == 0){
            numPage = 1L;
        } else if(list.size() == 0){
            numPage = 1L;
        } else {
            // 每页条数
            numPage = (long) Math.ceil(total / (double)aiconsultQue.getPageSize()) ;
        }
        if(list.size() == 0){
            return RLIST.error().message("暂无数据") ;
        }
        return RLIST.ok().data("data",list).data("total",total).data("numPage",numPage);
    }


}
